package com.colabo.j2ee.web.oaf.security;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.dao.DataAccessException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import com.colabo.j2ee.web.core.exception.ServiceException;
import com.colabo.j2ee.web.oaf.orgnization.model.SCUserProfileVO;
import com.colabo.j2ee.web.oaf.security.model.SCUserSecurityVO;


/**
 * 如果使用默认权限模型, 可以用这个bean来根据用户名取得用户权限数据, 这个接口除了默认UserDetailsService外不建议其他类实现.
 * 仅仅通过getBean方式调用.
 */
public interface IUserDetailsService extends UserDetailsService {
	static final String BEAN_ID = "userDetailsService";

	/**
	 * 该方法用于实际读取用户信息，由于用户登录名可能与用于验证的特征ID不一致，所以需要声明特征ID对应的字段
	 * @param username
	 * @param additionalInfo
	 * @return
	 * @throws UsernameNotFoundException
	 * @throws DataAccessException
	 */
	public UserDetails loadUserByUsername(String username, Object additionalInfo)
    throws UsernameNotFoundException, DataAccessException;
	/**
	 * 该方法会在登录成功后执行, 首先查找系统中是否存在ICustomUserDetailsService接口实现,
	 * 若存在此实现则调用实现完成登录成功后的操作, 否则继续进行默认操作
	 * 
	 * 默认操作包括将用户登录时间等属性保存到数据库, 并将用户名等属性写入session以便系统中使用.
	 * 
	 * @param request
	 * @param response
	 * @param username
	 * @throws ServiceException
	 */
	public void onSuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, 
			     String username)
			throws ServiceException;

	/**
	 * 该方法会在登录失败后执行, 首先查找系统中是否存在ICustomUserDetailsService接口实现,
	 * 若存在此实现则调用实现完成登录成功后的操作, 否则继续进行默认操作
	 * 
	 * 默认操作包括记录登录失败时间以及登录失败次数
	 * 
	 * @param request
	 * @param response
	 * @param username
	 * @throws ServiceException
	 */
	public void onUnsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, 
			String username,String pwd,String failed)
			throws ServiceException;

	/**
	 * 根据用户名取得用户userauth对象
	 * 
	 * @param username
	 * @return 若用户存在返回用户对象, 否则返回null
	 * @throws ServiceException
	 */
	public SCUserSecurityVO getUserAuthByUsername(String username) throws ServiceException;

	/**
	 * 根据用户对象获得用户权限对象
	 * 
	 * @param staff
	 * @return 若用户存在返回用户对象, 否则返回null
	 * @throws ServiceException
	 */
	public SCUserSecurityVO getUserAuthByStaff(SCUserProfileVO staff) throws ServiceException;

	/**
	 * 修改用户密码
	 */
	public String savePassword(String loginid, String oldPassword, String newPassword) throws ServiceException;

	/**
	 * 根据条件查询员工数据, map中key值为SCUserProfileVO中属性名称, 值为需要查询的值, 编码通过等于连接, 多个条件通过and连接
	 * 支持查询以下字段: loginid 模糊查询 staffid staffName 模糊查询 unitid unitName 模糊查询
	 * ownerUnitid ownerUnitName 模糊查询 positionid
	 * 
	 * kind adminLevel status idNumber sex tel email address
	 * 
	 * @param params
	 * @param offset
	 * @param pageSize
	 * @return
	 * @throws ServiceException
	 */
	public List query(Map params, int offset, int pageSize) throws ServiceException;

	/**
	 * 查询计数，用于分页
	 * 
	 * @param params
	 * @return 记录总数
	 * @throws ServiceException
	 */
	public int queryCount(Map params) throws ServiceException;

	/**
	 * 批量保存用户信息
	 * 
	 * @param insertBeans
	 * @param updateBeans
	 * @param delBeans
	 * @throws ServiceException
	 */
	public void batchCommit(List insertBeans, List updateBeans, List delBeans) throws ServiceException;
	
	/**
	 * 批量保存用户信息,与batchCommit方法的区别是，batchCommit方法选取的密码为默认密码，此方法选取的密码为前台设置的密码
	 * @param insertBeans
	 * @param updateBeans
	 * @param delBeans
	 * @throws ServiceException
	 */
	public void batchCommitByDs(List insertBeans, List updateBeans, List delBeans) throws ServiceException;

	/**
	 * 保存用户信息
	 * 
	 * @param user
	 * @return
	 * @throws ServiceException
	 */
	public SCUserSecurityVO save(SCUserSecurityVO user) throws ServiceException;

	/**
	 * 保存修改用户信息
	 * 
	 * @param user
	 * @return
	 * @throws ServiceException
	 */
	public SCUserSecurityVO update(SCUserSecurityVO user) throws ServiceException;

	/**
	 * 删除用户
	 * 
	 * @param user
	 * @throws ServiceException
	 */
	public void delete(SCUserSecurityVO user) throws ServiceException;

	/**
	 * 等到用户的权限
	 * 
	 * @param user
	 * @return
	 * @throws ServiceException
	 */
	public List getGrants(SCUserSecurityVO user);
	/**
	 * 
	 * @param params
	 * @param offset
	 * @param pageSize
	 * @return
	 * @throws ServiceException
	 */
	public List queryAuthUser(Map params, int offset, int pageSize) throws ServiceException;
	
	/**
	 * 
	 * @param params
	 * @return
	 * @throws ServiceException
	 */
	public int queryAuthUserCount(Map params) throws ServiceException;
	
	public void setAuthTableField(String authTableField);
	
	/**
	 * 批量修改用户状态
	 * @param updateBeans 用户信息对象集合
	 * @throws ServiceException
	 */
	public void batchCommitState(List updateBeans) throws ServiceException;
	
	/**
	 * 解锁所有被锁定用户
	 */
	public void unlockStaff() throws ServiceException ;
	
	/**
	 * 判断是否需要修改密码
	 * @param username 用户特征ID
	 * @return true 是首次登陆； false 相反
	 * @throws ServiceException
	 */
	public boolean needChangePassword(String username) throws ServiceException;

}
